﻿using System.Collections.Generic;
using UnityEngine;

namespace SubLib.MatchingSquare
{
    public class MeshToPolygonCollider : MonoBehaviour
    {
        [SerializeField] private MeshFilter _meshFilter;
        [Header("Mesh Reference")] public Mesh sourceMesh;

        [Header("Collider Settings")] public bool autoGenerate = true;
        public float simplificationTolerance = 0.01f;

        void Start()
        {
            if (_meshFilter)
            {
                sourceMesh = _meshFilter.mesh;
            }
            if (autoGenerate && sourceMesh != null)
            {
                GeneratePolygonColliderFromMesh();
            }
        }

        public void GeneratePolygonColliderFromMesh()
        {
            // 移除现有的PolygonCollider2D
            PolygonCollider2D existingCollider = GetComponent<PolygonCollider2D>();
            if (existingCollider != null)
            {
                DestroyImmediate(existingCollider);
            }

            // 添加新的PolygonCollider2D
            PolygonCollider2D polygonCollider = gameObject.AddComponent<PolygonCollider2D>();

            // 从Mesh获取顶点数据并生成碰撞路径
            Vector2[] collisionPath = GetCollisionPathFromMesh(sourceMesh);
            polygonCollider.SetPath(0, collisionPath);

            // 简化路径以减少顶点数量（可选）
            if (simplificationTolerance > 0)
            {
                polygonCollider.pathCount = 1;
                polygonCollider.SetPath(0, SimplifyPath(collisionPath, simplificationTolerance));
            }
        }

        private Vector2[] GetCollisionPathFromMesh(Mesh mesh)
        {
            List<Vector2> points = new List<Vector2>();

            // 获取Mesh的顶点
            Vector3[] vertices = mesh.vertices;

            // 将3D顶点转换为2D（忽略Z轴）
            foreach (Vector3 vertex in vertices)
            {
                points.Add(new Vector2(vertex.x, vertex.y));
            }

            return points.ToArray();
        }

        private Vector2[] SimplifyPath(Vector2[] path, float tolerance)
        {
            // 简单的道格拉斯-普克算法实现
            if (path.Length <= 2) return path;

            List<Vector2> simplified = new List<Vector2>();
            simplified.Add(path[0]);

            for (int i = 1; i < path.Length - 1; i++)
            {
                float distance = PointToLineDistance(path[i], path[0], path[path.Length - 1]);
                if (distance > tolerance)
                {
                    simplified.Add(path[i]);
                }
            }

            simplified.Add(path[path.Length - 1]);
            return simplified.ToArray();
        }

        private float PointToLineDistance(Vector2 point, Vector2 lineStart, Vector2 lineEnd)
        {
            float numerator = Mathf.Abs(
                (lineEnd.y - lineStart.y) * point.x -
                (lineEnd.x - lineStart.x) * point.y +
                lineEnd.x * lineStart.y - lineEnd.y * lineStart.x
            );

            float denominator = Mathf.Sqrt(
                Mathf.Pow(lineEnd.y - lineStart.y, 2) +
                Mathf.Pow(lineEnd.x - lineStart.x, 2)
            );

            return numerator / denominator;
        }
    }
}